const HashTable = require("../template")

function testHashTableComplexScenarios() {
  console.log(
    "1. 复杂数据类型测试:",
    (() => {
      const ht = new HashTable()
      
      // 存储各种复杂数据类型
      ht.set('object', { name: 'John', age: 30 })
      ht.set('array', [1, 2, 3, 4, 5])
      ht.set('function', () => 'hello')
      ht.set('null', null)
      ht.set('undefined', undefined)
      ht.set('boolean', true)
      ht.set('number', 42.5)
      
      const obj = ht.get('object')
      const arr = ht.get('array')
      const func = ht.get('function')
      
      return obj.name === 'John' &&
             obj.age === 30 &&
             Array.isArray(arr) &&
             arr.length === 5 &&
             typeof func === 'function' &&
             func() === 'hello' &&
             ht.get('null') === null &&
             ht.get('undefined') === undefined &&
             ht.get('boolean') === true &&
             ht.get('number') === 42.5
    })()
  )

  console.log(
    "2. 嵌套对象更新测试:",
    (() => {
      const ht = new HashTable()
      
      const user = { name: 'Alice', profile: { age: 25, city: 'NYC' } }
      ht.set('user', user)
      
      // 修改嵌套对象
      user.profile.age = 26
      user.profile.city = 'LA'
      
      const retrievedUser = ht.get('user')
      
      return retrievedUser.name === 'Alice' &&
             retrievedUser.profile.age === 26 &&
             retrievedUser.profile.city === 'LA'
    })()
  )

  console.log(
    "3. 循环引用处理测试:",
    (() => {
      const ht = new HashTable()
      
      const obj1 = { name: 'obj1' }
      const obj2 = { name: 'obj2' }
      
      // 创建循环引用
      obj1.ref = obj2
      obj2.ref = obj1
      
      ht.set('circular1', obj1)
      ht.set('circular2', obj2)
      
      const retrieved1 = ht.get('circular1')
      const retrieved2 = ht.get('circular2')
      
      return retrieved1.name === 'obj1' &&
             retrieved2.name === 'obj2' &&
             retrieved1.ref === retrieved2 &&
             retrieved2.ref === retrieved1
    })()
  )

  console.log(
    "4. 特殊键名测试:",
    (() => {
      const ht = new HashTable()
      
      // 测试各种特殊键名
      ht.set('', 'empty_string')
      ht.set(' ', 'space')
      ht.set('  ', 'multiple_spaces')
      ht.set('key with spaces', 'spaced_key')
      ht.set('key\nwith\nnewlines', 'newline_key')
      ht.set('key\twith\ttabs', 'tab_key')
      ht.set('key"with"quotes', 'quote_key')
      ht.set("key'with'quotes", 'single_quote_key')
      ht.set('key\\with\\backslashes', 'backslash_key')
      
      return ht.get('') === 'empty_string' &&
             ht.get(' ') === 'space' &&
             ht.get('  ') === 'multiple_spaces' &&
             ht.get('key with spaces') === 'spaced_key' &&
             ht.get('key\nwith\nnewlines') === 'newline_key' &&
             ht.get('key\twith\ttabs') === 'tab_key' &&
             ht.get('key"with"quotes') === 'quote_key' &&
             ht.get("key'with'quotes") === 'single_quote_key' &&
             ht.get('key\\with\\backslashes') === 'backslash_key' &&
             ht.size() === 9
    })()
  )

  console.log(
    "5. 大量键值对管理测试:",
    (() => {
      const ht = new HashTable()
      const count = 10000
      
      // 插入大量数据
      for (let i = 0; i < count; i++) {
        ht.set(`key_${i}`, {
          id: i,
          value: `value_${i}`,
          timestamp: Date.now(),
          metadata: { index: i, category: i % 10 }
        })
      }
      
      // 随机访问测试
      const randomIndices = Array.from({ length: 100 }, () => 
        Math.floor(Math.random() * count)
      )
      
      const randomAccessCorrect = randomIndices.every(index => {
        const key = `key_${index}`
        const value = ht.get(key)
        return value && 
               value.id === index && 
               value.value === `value_${index}` &&
               value.metadata.index === index
      })
      
      // 批量删除测试
      for (let i = 0; i < count / 2; i++) {
        ht.delete(`key_${i}`)
      }
      
      return randomAccessCorrect &&
             ht.size() === count / 2 &&
             ht.get('key_0') === undefined &&
             ht.get(`key_${count - 1}`).id === count - 1
    })()
  )

  console.log(
    "6. 动态扩容和缩容场景测试:",
    (() => {
      const ht = new HashTable(4, 0.5) // 低负载因子
      
      // 阶段1：插入数据触发扩容
      for (let i = 0; i < 10; i++) {
        ht.set(`phase1_${i}`, `value_${i}`)
      }
      
      const capacity1 = ht.getCapacity()
      const loadFactor1 = ht.getLoadFactor()
      
      // 阶段2：继续插入更多数据
      for (let i = 10; i < 50; i++) {
        ht.set(`phase2_${i}`, `value_${i}`)
      }
      
      const capacity2 = ht.getCapacity()
      const loadFactor2 = ht.getLoadFactor()
      
      // 阶段3：删除大量数据
      for (let i = 0; i < 30; i++) {
        ht.delete(`phase1_${i}`)
        ht.delete(`phase2_${i + 10}`)
      }
      
      const capacity3 = ht.getCapacity()
      const finalSize = ht.size()
      
      return capacity2 > capacity1 && // 扩容了
             capacity3 === capacity2 && // 没有缩容（通常哈希表不自动缩容）
             loadFactor2 < loadFactor1 && // 扩容后负载因子降低
             finalSize === 20 && // 最终大小正确
             ht.get('phase1_5') === undefined && // 删除的数据不存在
             ht.get('phase2_45') === 'value_45' // 剩余的数据存在
    })()
  )

  console.log(
    "7. 并发操作模拟测试:",
    (() => {
      const ht = new HashTable()
      
      // 模拟多个操作同时进行
      const operations = []
      
      // 操作1：批量插入
      for (let i = 0; i < 100; i++) {
        operations.push(() => ht.set(`concurrent_${i}`, `value_${i}`))
      }
      
      // 操作2：批量查找
      for (let i = 0; i < 100; i++) {
        operations.push(() => ht.get(`concurrent_${i}`))
      }
      
      // 操作3：批量更新
      for (let i = 0; i < 100; i++) {
        operations.push(() => ht.set(`concurrent_${i}`, `updated_${i}`))
      }
      
      // 操作4：批量删除
      for (let i = 0; i < 50; i++) {
        operations.push(() => ht.delete(`concurrent_${i}`))
      }
      
      // 随机执行操作
      const shuffledOps = operations.sort(() => Math.random() - 0.5)
      shuffledOps.forEach(op => op())
      
      // 验证最终状态
      let correctCount = 0
      for (let i = 0; i < 100; i++) {
        if (i < 50) {
          // 前50个应该被删除
          if (ht.get(`concurrent_${i}`) === undefined) {
            correctCount++
          }
        } else {
          // 后50个应该存在且被更新
          if (ht.get(`concurrent_${i}`) === `updated_${i}`) {
            correctCount++
          }
        }
      }
      
      return correctCount === 100 &&
             ht.size() === 50
    })()
  )

  console.log(
    "8. 错误恢复测试:",
    (() => {
      const ht = new HashTable()
      
      // 插入正常数据
      ht.set('normal1', 'value1')
      ht.set('normal2', 'value2')
      ht.set('normal3', 'value3')
      
      // 尝试一些边界操作
      ht.set('normal1', null) // 更新为null
      ht.set('normal2', undefined) // 更新为undefined
      ht.delete('normal3') // 删除
      ht.delete('nonexistent') // 删除不存在的键
      
      return ht.get('normal1') === null &&
             ht.get('normal2') === undefined &&
             ht.get('normal3') === undefined &&
             ht.has('normal1') === true &&
             ht.has('normal2') === true &&
             ht.has('normal3') === false &&
             ht.size() === 2
    })()
  )

  console.log(
    "9. this上下文复杂场景测试:",
    (() => {
      const complexObj = {
        multiplier: 3,
        processComplex: function(entries) {
          const ht = new HashTable()
          entries.forEach(([key, value]) => {
            ht.set(key, { ...value, processed: true, multiplier: this.multiplier })
          })
          return ht.size() * this.multiplier
        }
      }
      
      const testEntries = [
        ['a', { id: 1, name: 'Alice' }],
        ['b', { id: 2, name: 'Bob' }],
        ['c', { id: 3, name: 'Charlie' }]
      ]
      
      const result = complexObj.processComplex(testEntries)
      return result === 9 // 3 * 3 = 9
    })()
  )

  console.log(
    "10. 复杂对象this绑定场景测试:",
    (() => {
      const complexConfigObj = {
        config: { 
          threshold: 2, 
          transform: (value) => value * 2 
        },
        processWithComplexConfig: function(entries) {
          const ht = new HashTable()
          entries.forEach(([key, value]) => {
            const transformedValue = this.config.transform(value)
            ht.set(key, transformedValue)
          })
          return ht.size() >= this.config.threshold
        }
      }
      
      const testEntries = [['a', 1], ['b', 2], ['c', 3]]
      return complexConfigObj.processWithComplexConfig(testEntries) === true
    })()
  )

  console.log(
    "11. 内存泄漏防护测试:",
    (() => {
      const ht = new HashTable()
      
      // 创建大量临时对象
      for (let i = 0; i < 1000; i++) {
        const tempObj = { 
          id: i, 
          data: new Array(100).fill(i),
          timestamp: Date.now()
        }
        ht.set(`temp_${i}`, tempObj)
      }
      
      // 删除所有临时对象
      for (let i = 0; i < 1000; i++) {
        ht.delete(`temp_${i}`)
      }
      
      // 插入新数据验证哈希表仍然可用
      ht.set('final_test', 'success')
      
      return ht.size() === 1 &&
             ht.get('final_test') === 'success' &&
             ht.get('temp_0') === undefined
    })()
  )

  console.log(
    "12. 极端边界条件测试:",
    (() => {
      const ht = new HashTable(1, 0.1) // 最小容量，极低负载因子
      
      // 测试极端情况
      ht.set('', '')
      ht.set('a', 'a')
      ht.set('aa', 'aa')
      ht.set('aaa', 'aaa')
      
      // 强制触发多次扩容
      for (let i = 0; i < 100; i++) {
        ht.set(`extreme_${i}`, `extreme_value_${i}`)
      }
      
      // 验证所有数据都能正确获取
      let allCorrect = true
      for (let i = 0; i < 100; i++) {
        if (ht.get(`extreme_${i}`) !== `extreme_value_${i}`) {
          allCorrect = false
          break
        }
      }
      
      return allCorrect &&
             ht.get('') === '' &&
             ht.get('a') === 'a' &&
             ht.get('aa') === 'aa' &&
             ht.get('aaa') === 'aaa' &&
             ht.size() === 104 &&
             ht.getCapacity() > 1
    })()
  )
}

testHashTableComplexScenarios()
